<template>
    <div class="form-rules">
        <a-divider orientation="left">表单校验</a-divider>

        <div class="panel-inner-box">
            <div class="panel-form-item check">
                <div class="item-label">是否必填</div>
                <div class="item-input">
                    <a-switch size="small" v-model:checked="data.defaultRule.required" @change="requiredChange" />
                </div>
            </div>
            <div class="panel-form-item">
                <div class="item-label">校验方式</div>
                <div class="item-input">
                    <a-select v-model:value="data.defaultRule.trigger" mode="tags" placeholder="校验方式"
                        style="width: 100%">
                        <a-select-option value="change">change</a-select-option>
                        <a-select-option value="blur">blur</a-select-option>
                    </a-select>
                </div>
            </div>
            <div class="panel-form-item">
                <div class="item-label">
                    校验类型
                </div>
                <div class="item-input flex">
                    <a-select v-model:value="data.defaultRule.type" placeholder="校验类型" style="width: 100%">
                        <a-select-option v-for="item in checkTypeList"
                            :value="item.name">{{ item.name }}</a-select-option>
                    </a-select>
                    <a-tooltip placement="topRight">
                        <template #title>
                            <div class="check-type-list-desc" v-for="item in checkTypeList">
                                <span class="blod-font">{{ item.name }}</span>：{{ item.desc }}
                            </div>
                        </template>
                        <QuestionCircleOutlined class="tips-icon" />
                    </a-tooltip>
                </div>
            </div>
            <div class="panel-form-item">
                <div class="item-label">提示信息</div>
                <div class="item-input">
                    <a-input placeholder="提示信息" v-model:value="data.defaultRule.message"></a-input>
                </div>
            </div>
        </div>

        <template v-for="(item, index) in selectItem.rules">
            <div class="panel-inner-box" v-if="!item.hasOwnProperty('required')">

                <span class="delete-rule-btn" title="删除规则" @click="deleteRules(index)">
                    <CloseCircleFilled />
                </span>

                <div class="panel-form-item">
                    <div class="item-label">校验方式</div>
                    <div class="item-input">
                        <a-select v-model:value="item.trigger" mode="tags" placeholder="校验方式" style="width: 100%">
                            <a-select-option value="change">change</a-select-option>
                            <a-select-option value="blur">blur</a-select-option>
                        </a-select>
                    </div>
                </div>
                <div class="panel-form-item">
                    <div class="item-label">校验类型</div>
                    <div class="item-input flex">
                        <a-select v-model:value="item.type" placeholder="校验类型" style="width: calc(100% - 14px)">
                            <a-select-option v-for="item in checkTypeList"
                                :value="item.name">{{ item.name }}</a-select-option>
                        </a-select>
                        <a-tooltip placement="topRight">
                            <template #title>
                                <div class="check-type-list-desc" v-for="item in checkTypeList">
                                    <span class="blod-font">{{ item.name }}</span>：{{ item.desc }}
                                </div>
                            </template>
                            <QuestionCircleOutlined class="tips-icon" />
                        </a-tooltip>
                    </div>
                </div>
                <div class="panel-form-item">
                    <div class="item-label">正则校验</div>
                    <div class="item-input">
                        <a-input v-model:value="item.pattern" placeholder="正则表达式">
                            <template #suffix>
                                <a-dropdown>
                                    <ProfileOutlined title="内置正则" />
                                    <template #overlay>
                                        <a-menu>
                                            <a-menu-item v-for="patternItem in defaultPattern"
                                                @click="setPattern(item,patternItem)">
                                                {{ patternItem.name }}
                                            </a-menu-item>
                                        </a-menu>
                                    </template>
                                </a-dropdown>
                            </template>
                        </a-input>
                    </div>
                </div>

                <template v-if="getIfType(item.type)">
                    <div class="panel-form-item">
                        <div class="item-label">字段长度</div>
                        <div class="item-input">
                            <a-input-number :min="0" v-model:value="item.len" placeholder="字段长度" />
                        </div>
                    </div>
                    <div class="panel-form-item">
                        <div class="item-label">最小长度</div>
                        <div class="item-input">
                            <a-input-number :min="0" v-model:value="item.min" placeholder="最小长度" />
                        </div>
                    </div>
                    <div class="panel-form-item">
                        <div class="item-label">最大长度</div>
                        <div class="item-input">
                            <a-input-number :min="0" v-model:value="item.max" placeholder="最大长度" />
                        </div>
                    </div>
                </template>

                <div class="panel-form-item">
                    <div class="item-label">提示信息</div>
                    <div class="item-input">
                        <a-input placeholder="提示信息" v-model:value="item.message"></a-input>
                    </div>
                </div>
            </div>
        </template>
        <a-button type="primary" size="small" @click="addRules" style="margin-bottom: 15px;">新增规则</a-button>
    </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import { hasProperty, regexToString } from '../../util/util.js'

const props = defineProps({
    selectItem: {
        type: Object,
    },
})

// 校验类型
const checkTypeList = [
    { name: "string", desc: "必须是string类型" },
    { name: "number", desc: "必须是number类型" },
    { name: "boolean", desc: "必须是boolean类型" },
    { name: "function", desc: "必须是函数类型" },
    { name: "regexp", desc: "必须是regexp的实例或在创建新regexp时不生成异常的字符串" },
    { name: "integer", desc: "必须是数字和整数类型" },
    { name: "float", desc: "必须是数字类型和浮点数字" },
    { name: "array", desc: "必须是由array.isArray确定的数组" },
    { name: "object", desc: "必须是object类型 而不是Array.isArray" },
    { name: "enum", desc: "值必须存在于枚举中" },
    { name: "date", desc: "值必须由date确定为有效" },
    { name: "url", desc: "必须是url类型" },
    { name: "hex", desc: "必须是hex类型" },
    { name: "email", desc: "必须是电子邮件类型" },
    { name: "any", desc: "可以是任何类型" }
]

// 内置正则
const defaultPattern = [
    { name: "英文和数字", pattern: /^[A-Za-z0-9]{4,40}$/ },
    { name: "Email地址", pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/ },
    { name: "域名", pattern: /^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\/?$/ },
    { name: "手机号码", pattern: /^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/ },
    { name: "身份证号", pattern: /^\d{15}|\d{18}$/ },
]

const getRequiredObj = computed(() => {
    // 非空判断
    const rules = props.selectItem?.rules ?? [];
    // 判断当前是否存在必填项的规则
    const defaultRule = rules.find(rule => rule.hasOwnProperty('required'));

    return defaultRule || {
        required: false,
        message: "必填项",
        type: "string",
        trigger: ["change"]
    };
});

const data = reactive({
    defaultRule: getRequiredObj,
})

// 必填项改变时
const requiredChange = (value) => {
    if (value) {
        if (props.selectItem.rules == undefined) {
            props.selectItem.rules = [data.defaultRule]
        } else if (!hasProperty(props.selectItem.rules, "required")) {
            props.selectItem.rules.push(data.defaultRule)
        }
    } else {
        props.selectItem.rules.forEach((item, index) => {
            if (item.hasOwnProperty('required')) {
                props.selectItem.rules.splice(index, 1)
            }
        })
    }
}

// 判断类型
const getIfType = (type) => {
    if (type == 'string' || type == 'number' || type == 'array' || type == 'url' || type == 'email') {
        return true;
    } else {
        return false;
    }
}


// 新增规则
const addRules = () => {
    if (!props.selectItem.rules) props.selectItem.rules = []
    props.selectItem.rules.push({
        message: "",
        trigger: ["change"],
        type: "string",
        // pattern: "",
        // len: null,
        // min: 15,
        // max: 18
    },)
}

// 删除规则
const deleteRules = (index) => {
    props.selectItem.rules.splice(index, 1)
}


// 设置内置正则
const setPattern = (item, patternItem) => {

    item.pattern = regexToString(patternItem.pattern);
}


</script>

<style lang="less" scoped>
.panel-inner-box {
    position: relative;

    &:hover {
        .delete-rule-btn {
            opacity: 0.6;
            &:hover {
                opacity: 1;
            }
        }
    }

    .delete-rule-btn {
        position: absolute;
        right: -8px;
        top: -8px;
        color: #898989;
        cursor: pointer;
        z-index: 1;
        font-size: 18px;
        opacity: 0;
        transition: all 0.2s;
    }
}
</style>